// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IOS_WEB_VIEW_PUBLIC_CWV_AUTOFILL_CONTROLLER_DELEGATE_H_
#define IOS_WEB_VIEW_PUBLIC_CWV_AUTOFILL_CONTROLLER_DELEGATE_H_

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class CWVAutofillController;
@class CWVAutofillForm;
@class CWVAutofillFormSuggestion;
@class CWVAutofillProfile;
@class CWVCreditCard;
@class CWVCreditCardSaver;
@class CWVCreditCardVerifier;
@class CWVPassword;

// User decision for saving / updating an autofill profile.
typedef NS_ENUM(NSInteger, CWVAutofillProfileUserDecision) {
  // The user accepted the change.
  CWVAutofillProfileUserDecisionAccepted = 0,
  // The user declined the change.
  CWVAutofillProfileUserDecisionDeclined,
  // The user ignored the prompt.
  CWVAutofillProfileUserDecisionIgnored,
};

// User decision for saving / updating password.
// Note: CWVPasswordUserDecisionNever is only used in saving scenarios.
typedef NS_ENUM(NSInteger, CWVPasswordUserDecision) {
  CWVPasswordUserDecisionNotThisTime =
      0,                         // Do not save / update password this time.
  CWVPasswordUserDecisionNever,  // Never save password for this site.
  CWVPasswordUserDecisionYes,    // Save / update password.
};

// All possible leak type combinations.
// Keep up to date with password_manager::CredentialLeakFlags in
// components/password_manager/core/browser/leak_detection_dialog_utils.h.
typedef NS_OPTIONS(NSInteger, CWVPasswordLeakType) {
  // The leaked password is currently saved.
  CWVPasswordLeakTypeSaved = 1 << 0,
  // The leaked password is also used on other sites.
  CWVPasswordLeakTypeUsedOnOtherSites = 1 << 1,
  // The leaked password is synced to a remote store.
  CWVPasswordLeakTypeSynced = 1 << 2,
};

// Protocol to receive callbacks related to autofill.
// |fieldIdentifier| identifies the html field. Generated by
// __gCrWeb.form.getFieldIdentifier in form.js.
// |fieldType| is the 'type' attribute of the html field.
// |formName| is the 'name' attribute of a html <form>.
// |value| is the 'value' attribute of the html field.
// Example:
// <form name='_formName_'>
//   <input id='_fieldIdentifier_' value='_value_' type='_fieldType_'>
// </form>
@protocol CWVAutofillControllerDelegate<NSObject>

@optional

// Called when a form field element receives a "focus" event.
// |userInitiated| is YES if field was focused as a result of user interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
    didFocusOnFieldWithIdentifier:(NSString*)fieldIdentifier
                        fieldType:(NSString*)fieldType
                         formName:(NSString*)formName
                          frameID:(NSString*)frameID
                            value:(NSString*)value
                    userInitiated:(BOOL)userInitiated;

// Called when a form field element receives an "input" event.
// |userInitiated| is YES if field received input as a result of user
// interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
    didInputInFieldWithIdentifier:(NSString*)fieldIdentifier
                        fieldType:(NSString*)fieldType
                         formName:(NSString*)formName
                          frameID:(NSString*)frameID
                            value:(NSString*)value
                    userInitiated:(BOOL)userInitiated;

// Called when a form field element receives a "blur" (un-focused) event.
// |userInitiated| is YES if field was blurred as a result of user interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
    didBlurOnFieldWithIdentifier:(NSString*)fieldIdentifier
                       fieldType:(NSString*)fieldType
                        formName:(NSString*)formName
                         frameID:(NSString*)frameID
                           value:(NSString*)value
                   userInitiated:(BOOL)userInitiated;

// Called when a form was submitted.
// |userInitiated| is YES if form was submitted as a result of user interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
     didSubmitFormWithName:(NSString*)formName
                   frameID:(NSString*)frameID
             userInitiated:(BOOL)userInitiated;

// Called when |forms| are found in a frame with |frameID|.
// Will be called after initial load and after any form mutations.
// Always includes all forms in the frame.
- (void)autofillController:(CWVAutofillController*)autofillController
              didFindForms:(NSArray<CWVAutofillForm*>*)forms
                   frameID:(NSString*)frameID;

// Called when it is possible to save a new credit card. This is usually called
// after a new card was entered in a form and submitted.
// |saver| encapsulates information needed to assist with this save attempt.
// Life time of |saver| should be managed by the delegate.
- (void)autofillController:(CWVAutofillController*)autofillController
    saveCreditCardWithSaver:(CWVCreditCardSaver*)saver;

// Called when the user needs to use |verifier| to verify a credit card.
// Lifetime of |verifier| should be managed by the delegate.
- (void)autofillController:(CWVAutofillController*)autofillController
    verifyCreditCardWithVerifier:(CWVCreditCardVerifier*)verifier;

// Called when user needs to decide on whether or not to save the |password|.
// This can happen when user successfully logs into a web site with a new
// username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
// Not implementing it is equivalent of not calling |decisionHandler|.
- (void)autofillController:(CWVAutofillController*)autofillController
    decideSavePolicyForPassword:(CWVPassword*)password
                decisionHandler:
                    (void (^)(CWVPasswordUserDecision decision))decisionHandler;

// Called when user needs to decide on whether or not to update the |password|.
// This can happen when user successfully logs into a web site with a new
// password and an existing username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
// Not implementing it is equivalent of not calling |decisionHandler|.
- (void)autofillController:(CWVAutofillController*)autofillController
    decideUpdatePolicyForPassword:(CWVPassword*)password
                  decisionHandler:(void (^)(CWVPasswordUserDecision decision))
                                      decisionHandler;

// Called if a submitted username and password combination is determined to be
// leaked for |URL|. |leakType| provides additional context of the leak.
// Deprecated: Use |autofillController:notifyUserOfPasswordLeakOnURL:username:|.
- (void)autofillController:(CWVAutofillController*)autofillController
    notifyUserOfPasswordLeakOnURL:(NSURL*)URL
                         leakType:(CWVPasswordLeakType)leakType;

// Called if a submitted username and password combination is determined to be
// leaked for |URL|. |leakType| provides additional context of the leak.
// |username| The username whose password is leaked.
- (void)autofillController:(CWVAutofillController*)autofillController
    notifyUserOfPasswordLeakOnURL:(NSURL*)URL
                         leakType:(CWVPasswordLeakType)leakType
                         username:(NSString*)username;

// Called when the user taps on the "Suggest password..." suggestion when trying
// to sign up for a new account on a site. |generatedPassword| is a randomly
// generated password that, if accepted in |decisionHandler|, will be injected
// into the form. |decisionHandler| must be called.
- (void)autofillController:(CWVAutofillController*)autofillController
    suggestGeneratedPassword:(NSString*)generatedPassword
             decisionHandler:(void (^)(BOOL accept))decisionHandler;

// Called when the user should be prompted to save or update a profile.
// |newProfile| The new profile that is being considered.
// |oldProfile| The old profile, that if non-nil, will be overwritten.
// |decisionHandler| Must be called when the user makes a decision. If accepted,
// any property changes to |newProfile| will also be committed. This allows the
// user to make any edits if they wish.
// If this method is not implemented, |newProfile| will be automatically saved.
- (void)autofillController:(CWVAutofillController*)autofillController
    confirmSaveForNewAutofillProfile:(CWVAutofillProfile*)newProfile
                          oldProfile:(nullable CWVAutofillProfile*)oldProfile
                     decisionHandler:
                         (void (^)(CWVAutofillProfileUserDecision decision))
                             decisionHandler;

@end

NS_ASSUME_NONNULL_END

#endif  // IOS_WEB_VIEW_PUBLIC_CWV_AUTOFILL_CONTROLLER_DELEGATE_H_
